import re

from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings

from apps.headline.models import Article
from apps.invite.models import Enterprise
from apps.questions.models import Label, Question, Reply
from apps.users.models import User
from django.contrib.auth import authenticate



class LoginSerializers(serializers.ModelSerializer):
    username = serializers.CharField(label='用户名')
    token = serializers.CharField(label='JWT Token', read_only=True)

    class Meta:
        model = User
        fields = ('id', 'username', 'password', 'token', 'mobile', 'avatar')
        # fields = '__all__'
        extra_kwargs = {
            'password': {
                'write_only': True
            },
            'mobile': {
                'read_only': True
            },
            'avatar': {
                'read_only': True
            },
        }

    def validate(self, attrs):
        username = attrs['username']
        password = attrs['password']
        try:
            user = User.objects.get(mobile=username)
        except User.DoesNotExist:
            raise serializers.ValidationError('用户名或密码错误')
        else:
            if not user.check_password(password):
                raise serializers.ValidationError('用户名或密码错误')
            attrs['user'] = user
        return attrs

    def create(self, validated_data):

        user = validated_data['user']

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        user.token = token
        return user


class RegisterUserSerializer(serializers.ModelSerializer):

    username = serializers.CharField(label='真实姓名')
    sms_code = serializers.CharField(label='短信验证码', required=True, write_only=True)
    token = serializers.CharField(label='JWT token', read_only=True)

    class Meta:
        model = User
        fields = ('id', 'username', 'password','token', 'mobile', 'avatar', 'sms_code')
        extra_kwargs = {
            'username': {
                'min_length': 5,
                'max_length': 20,
                'error_messages': {
                    'min_length': '用户名最小长度为5',
                    'max_length': '用户名最大长度为20'
                }
            },
            'password': {
                'write_only': True,
                'min_length': 8,
                'max_length': 20,
                'error_messages': {
                    'min_length': '密码最小长度为8',
                    'max_length': '密码最大长度为20'
                }
            },
            'avatar': {
                'read_only': True,
            },

        }

    # 数据验证
    def validate(self, attrs):
        # 提取参数
        username = attrs['username']
        password = attrs['password']
        sms_code = attrs.pop('sms_code')
        mobile = attrs['mobile']

        # 验证参数
        if not all([username, password, mobile]):
            raise serializers.ValidationError('缺少必传参数')
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            raise serializers.ValidationError('密码格式错误')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            raise serializers.ValidationError('手机号格式错误')

        # 判断是否存在
        count = User.objects.filter(mobile=mobile).count()
        if count:
            raise serializers.ValidationError('手机号已注册')

        # 链接redis，获取验证码，验证验证码
        redis_conn = get_redis_connection('code')
        sms_code_redis = redis_conn.get('sms_%s' % mobile)
        if not sms_code_redis:
            raise serializers.ValidationError('验证码已过期')

        # 判断验证码是否正确，redis中获取后解码
        if sms_code != sms_code_redis.decode():
            raise serializers.ValidationError('短信验证码错误')

        return attrs

    # 重写create方法
    def create(self, validated_data):

        # user = super().create(validated_data=validated_data)
        user = User.objects.create_user(**validated_data)
        # 密码加密
        user.set_password(validated_data['password'])

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        user.token = token
        user.save()
        return user


class LabelSerializer(serializers.ModelSerializer):

    class Meta:
        model = Label
        fields = ('id', 'label_name')


class QuestionSerializer(serializers.ModelSerializer):

    user = serializers.StringRelatedField(read_only=True)
    labels = serializers.StringRelatedField(many=True, read_only=True)

    class Meta:
        model = Question
        fields = ('id', 'createtime', 'labels', 'reply', 'replyname', 'replytime', 'title',
                  'unuseful_count', 'useful_count', 'user', 'visits')


class UserSimpleSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'username', 'avatar')


class SubReplySerializer(serializers.ModelSerializer):
    user = UserSimpleSerializer(label='简单个人信息')

    class Meta:
        model = Reply
        fields = ('id', 'content', 'createtime', 'useful_count', 'unuseful_count', 'user')


class ReplySerializer(serializers.ModelSerializer):

    user = UserSimpleSerializer(label='简单个人信息')
    subs = SubReplySerializer(label='父评论', many=True)
    parent = SubReplySerializer(label='父评论')

    class Meta:
        model = Reply
        fields = ('id', 'content', 'createtime', 'useful_count', 'problem',
                  'unuseful_count', 'subs', 'user', 'parent')


class ArticleSerializerSimple(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = ('id', 'title')


class UserForArticleSerializer(serializers.ModelSerializer):
    articles = ArticleSerializerSimple(read_only=True, many=True)

    class Meta:
        model = User
        fields = ('id', 'username', 'avatar', 'articles', 'fans')


class ArticleSerializer(serializers.ModelSerializer):
    user = UserForArticleSerializer(read_only=True)
    collected = serializers.BooleanField(default=False)

    class Meta:
        model = Article
        fields = ("id", "title", "content", "createtime", "user", "collected_users", "collected", "image")


class EnterpriseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Enterprise
        fields = ('id', 'name', 'labels', 'logo', 'recruits', 'summary')


class UserSerializer(serializers.ModelSerializer):
    username = serializers.CharField(read_only=True)
    labels = LabelSerializer(label='标签', many=True, read_only=True)
    questions = QuestionSerializer(label='问题', many=True, read_only=True)
    answer_question = ReplySerializer(label='回答', many=True, read_only=True)
    collected_articles = ArticleSerializer(label='文章', many=True, read_only=True)
    enterpises = EnterpriseSerializer(label='企业', many=True, read_only=True)
    birthday = serializers.DateField(format="%Y-%m-%d", input_formats=["%Y-%m-%d"])
    realname = serializers.CharField(default=None)

    class Meta:
        model = User
        fields = ('id', 'username', 'mobile', 'realname', 'birthday', 'sex', 'avatar', 'website', 'email', 'city',
                  'address', 'labels', 'questions', 'answer_question', 'collected_articles', 'enterpises')


class UserPwdSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('password',)
        extra_kwargs = {
            'password': {'write_only': True}
        }

    def update(self, instance, validated_data):
        user = super().update(instance, validated_data)
        user.set_password(validated_data['password'])
        user.save()
        return user


class UserLabelSerializer(serializers.ModelSerializer):
    labels = serializers.PrimaryKeyRelatedField(required=True, many=True, queryset=Label.objects.all())

    class Meta:
        model = User
        fields = ('id', 'labels')